import logging
import re
import oabot_model

from waveapi import simplejson as json
from waveapi import events
from waveapi import model
from waveapi import robot
from waveapi import robot_abstract
from waveapi import document
from waveapi import ops
from google.appengine.api import urlfetch
from xml.dom import minidom

class Command(object):
    def __init__(self, name, pattern, func):
        self.name = name
        self.pattern = pattern
        self.func = func
    def __call__(self, properties, context, user, **kwargs):
        return self.func(properties, context, user, **kwargs)

def OnRobotAdded(properties, context):
    """Invoked when the robot has been added."""
    root_wavelet = context.GetRootWavelet()
    text = "I am the Open Australia Bot. Please find how to use me below."
    text += "Available commands:\n"
    text += "-----------------------------------------------------\n"
    text += "search_rep reps SEAT\n"
    text += "    Find the House Of Representatives Member for SEAT\n"
    text += "search_rep senate STATE\n"
    text += "    Find the Senators for STATE (NSW, QLD, VIC, TAS, SA, WA, ACT, NT) \n"
    text += "-----------------------------------------------------\n"
    root_wavelet.CreateBlip().GetDocument().SetText(text)
  
def onBlipSubmitted(properties, context):
    """Invoked when a new wavelet blip is created"""
    oakey = "F8c6oBD4YQsvEAGJT8DUgL8p"
    blip = context.GetBlipById(properties['blipId'])
    user = blip.GetCreator()
    words = blip.GetDocument().GetText()
    logging.debug("user: %s" % user)
    logging.debug("words: %s" % str(words))
    
    commands = []
    commands.append(Command("help", r"^[hH][eE][lL][pP]$", help))
    commands.append(Command("search_rep", r"^search_rep ?(?P<HOUSE>[\w]+)? ?(?P<SEAT>[\w\s\w]+)?$", search_rep))
    commands.append(Command("search_party", r"^search_party ?(?P<PARTY>[\w]+)?$", search_party))
    commands.append(Command("search_hansard", r"^search_hansard ?(?P<HOUSE>[\w]+)? ?(?P<STYPE>[\w]+)? ?(?P<SEARCH>[w\s\w]+)?$", search_hansard))
    
    for command in commands:
        pat = re.compile(command.pattern)
        m = pat.search(words)
        if m:
            logging.debug("groupdict: %s" % str(m.groupdict()))
            command(properties, context, user, **m.groupdict())
            return  
    return
    
def help(properties, context, user, **kwargs):
    blip = context.GetBlipById(properties['blipId'])
    text = "You(%s) requested help.\n" % user
    text += "Available commands:\n"
    text += "-----------------------------------------------------\n"
    text += "search_rep HOUSE (rep, senate) SEAT (seat name or state)\n"
    text += "    Find the House Of Representatives Member for SEAT\n"
    text += "search_party PCODE DATE PARTY STRING\n"
    text += "    list the Representatives for the Party depending on input\n\n"
    text += "-----------------------------------------------------\n"
    blip.CreateChild().GetDocument().SetText(text)
  
def search_rep(properties, context, user, **kwargs):
    house = kwargs.get("HOUSE", None)
    seat = kwargs.get("SEAT", None)
    blip = context.GetBlipById(properties['blipId'])
    payload = "key=F8c6oBD4YQsvEAGJT8DUgL8p"
    url = '';
    if house == "reps":
        url = "http://www.openaustralia.org/api/getRepresentative"
        payload += "&division="
        payload += seat
    elif house == "senate":
        url = "http://www.openaustralia.org/api/getSenators"
        payload += "&state="+seat
    
    payload += "&output=xml"
    
    logging.debug("payload: %s", payload)
    
    res = urlfetch.fetch(url=url, payload=payload, method=urlfetch.POST)
    if res.status_code == 200:
        firstname = ''
        lastname = ''
        xmldoc = minidom.parseString(res.content)
        if house == "reps":
            for result in xmldoc.getElementsByTagName('result'):
                try:
                        firstname = result.getElementsByTagName('first_name')[0].firstChild.data
                        lastname = result.getElementsByTagName('last_name')[0].firstChild.data
                        party = result.getElementsByTagName('party')[0].firstChild.data
                        dateenteredparl = result.getElementsByTagName('entered_house')[0].firstChild.data
                        imageurl = 'http://www.openaustralia.org/'+result.getElementsByTagName('image')[0].firstChild.data
                        personid = result.getElementsByTagName('person_id')[0].firstChild.data
                        finres = "Member for "+seat+"\n\n"+firstname+" "+lastname
                        finres += "\n"
                        finres += party
                        finres += "\n"
                        finres += dateenteredparl+"\n\n"
                        new_blip = blip.CreateChild()
                        new_blip.GetDocument().SetText(finres)
                        new_blip.GetDocument().AppendElement(document.Image(imageurl))
                        new_blip.GetDocument().AppendElement(document.FormElement(
                                                                              document.ELEMENT_TYPE.BUTTON,
                                                                              personid,
                                                                              value='Track Representative',
                                                                              ))
                except IndexError, ValueError:
                    pass
        elif house == "senate":
            finres = 'Results\n\n'
            for result in xmldoc.getElementsByTagName('result'):
                new_blip = blip.CreateChild()
                matches = result.getElementsByTagName('match')
                for match in matches:
                    imageurl = "http://www.openaustralia.org/images/mpsL/"+match.getElementsByTagName('person_id')[0].firstChild.data+".jpg"
                    finres += match.getElementsByTagName('name')[0].firstChild.data
                    finres += "\n"
                    new_blip.GetDocument().AppendElement(document.Image(imageurl))
                    finres += "Party: "+match.getElementsByTagName('party')[0].firstChild.data
                    finres += "\n\n"
                    new_blip.GetDocument().SetText(finres)
        #finres = res.content
        #finres += xmldoc.toxml()
        
        
def search_party(properties, context, user, **kwargs):
    search_pcode = kwargs.get("PCODE")
    search_date = kwargs.get("DATE")
    search_party = kwargs.get("PARTY")
    search_string = kwargs.get("STRING")
    
    if search_pcode == "-":
        search_pcode = ''
    if search_date == "-":
        search_date = ''
    if search_party == "-":
        search_party = ''
    if search_string == "-":
        search_string = ''
        
    url = "http://www.openaustralia.org/api/getRepresentatives"
    payload = "key=F8c6oBD4YQsvEAGJT8DUgL8p"
    payload += "&postcode="
    payload += search_pcode
    payload += "&date="
    payload += search_date
    payload += "&party="
    payload += search_party
    payload += "&search="
    payload += search_string
    payload += "&output=xml"
    
    res = urlfetch.fetch(url=url, payload=payload, method=urlfetch.POST)
    if res.status_code == 200:
        xmldoc = minidom.parseString(res.content)
        finres = "Party Members for"
        finres += search_party
        
        for result in xmldoc.getElementsByTagName('result'):
            try:
                for rep in result.getElementsByTagName('match'):
                    name = rep.getElementsByTagName('name')
                    finres += name
                    finres += "\n"
            except IndexError, ValueError:
                pass
            
def search_senate(properties, context, user, **kwargs):
    search_type = kwargs.get("STYPE")

def search_hansard(properties, context, user, **kwargs):
    """ Let's see if we can build a hansard searcher"""
    house = kwargs.get("HOUSE")
    stype = kwargs.get("STYPE")
    search = kwargs.get("SEARCH")
    blip = context.GetBlipById(properties['blipId'])
    url = "http://www.openaustralia.org/api/getDebates"
    payload = "key=F8c6oBD4YQsvEAGJT8DUgL8p"
    if house == 'reps':
        payload += "&type=representatives"
    else:
        payload += "&type=senate"
    
    if stype == 'date':
        payload += '&date='+search
    elif stype == 'search':
        payload += '&search='+search
        
    payload += '&output=xml'
    
    logging.debug("URL: %s", payload)
    
    res = urlfetch.fetch(url=url, payload=payload, method=urlfetch.POST)
    if res.status_code == 200:
        xmldoc = minidom.parseString(res.content)
        for result in xmldoc.getElementsByTagName('result'):
            finres = ''
            for row in result.getElementsByTagName('rows'):
                try:
                    new_blip = blip.CreateChild()
                    matches = row.getElementsByTagName('match')
                    for match in matches:
                        #finres += match.getElementsByTagName('body')[0].firstChild.data
                        #finres += "\n"
                        finres += "http://openaustralia.org/"+match.getElementsByTagName('listurl')[0].firstChild.data
                        finres += "\n\n"
                        
                        
                except IndexError, ValueError:
                    pass
                
                new_blip.GetDocument().SetText(finres)
    
def follow_rep(properties, context):
    #  This function will allow the participant to join an existing wave or create a new one
    member_id = properties['button']
    does_track_wave_exist(member_id, context)    
    
def does_track_wave_exist(member_id,context):
    query = oabot_model.rep_wave_track.all()
    query.filter("rep_member_id =", member_id)
    result = query.fetch(1)
    if result:
        for r in result:
            wave_id = r.rep_wave_id
    else:
        root_wavelet = context.GetRootWavelet()
        rep_wave = robot_abstract.NewWave(context, root_wavelet.GetParticipants())
        rep_wavelet = rep_wave.CreateBlip()
        rep_wavelet.GetDocument().SetText("Hello There")
        logging.debug("New Wave Created")
        wave_id = rep_wavelet.GetWaveID()
        logging.debug("Member ID: %s", member_id)
        logging.debug("New Wave Id: %s",wave_id)
        
        #Create a New Wave Record
        tracker = oabot_model.rep_wave_track()
        tracker.rep_member_id = int(member_id)
        tracker.rep_wave_id = wave_id
        tracker.put()
        
    return wave_id

#def createtrackwave(properties, context):
#    tracker_wave = context.AddWave(context.GetParticipants())
#    tracker_root = oabot_model.tracker_wave.GetRootWaveletId()
#    new_blip = tracker_root.CreateBlip()
#    new_blip.GetDocument().SetText("Welcome to the Tracker Wave")
#    trackwave = rep_wave_track(
#                               rep_wave_id = tracker_wave.GetRootWaveletId(),
#                               rep_feed_url = 'http://www.openaustralia.org/mp/rss/'+properties['button']+'.rdf'
#                               )
#    trackwave.put()
                    
def Notify(context):
    root_wavelet = context.GetRootWavelet()
    root_wavelet.CreateBlip().GetDocument().SetText("Hi everybody!")

if __name__ == '__main__':
    myRobot = robot.Robot('openausbot', 
      image_url='http://openausbot.appspot.com/icon.png',
      version='89',
      profile_url='http://openausbot.appspot.com/')
    myRobot.RegisterHandler(events.WAVELET_SELF_ADDED, OnRobotAdded)
    myRobot.RegisterHandler(events.BLIP_SUBMITTED, onBlipSubmitted)
    myRobot.RegisterHandler(events.FORM_BUTTON_CLICKED, follow_rep)
    myRobot.Run()